﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Web.Controllers
{
    using Commands.Accounts;
    using ECommon.Utilities;
    using ENode.Commanding;
    using Infrastructure;
    using QueryServices;
    using System.Threading;
    using System.Threading.Tasks;

    using Web.Extensions;
    using Web.Models;
    using Web.Services;


    public class AccountController : Controller
    {
        private readonly IAuthenticationService _authenticationService;
        private readonly ICommandService _commandService;
        private readonly IAccountQueryService _queryService;
        private readonly IContextService _contextService;

        public AccountController(IContextService contextService, IAuthenticationService authenticationService, ICommandService commandService, IAccountQueryService queryService)
        {
            _contextService = contextService;
            _authenticationService = authenticationService;
            _commandService = commandService;
            _queryService = queryService;
        }


        #region register


        [HttpGet]
        public ActionResult Register()
        {
            return View();
        }

        [HttpPost]
        [AjaxValidateAntiForgeryToken]
        [AsyncTimeout(5000)]
        public async Task<ActionResult> Register(RegisterModel model, CancellationToken token)
        {
            var result = await _commandService.ExecuteAsync(
                new RegisterNewAccountCommand(
                    ObjectId.GenerateNewStringId(),
                    model.AccountName,
                    model.Password),
                    CommandReturnType.EventHandled);

            var commandResult = result.Data;
            if (commandResult.Status == CommandStatus.Failed)
            {
                if (commandResult.ExceptionTypeName == typeof(DuplicateAccountException).Name)
                {
                    return Json(new { success = false, errorMsg = "该账号已被注册，请用其他账号注册。" });
                }
                return Json(new { success = false, errorMsg = result.ErrorMessage });
            }

            string sessionId = ObjectId.GenerateNewStringId();
            _authenticationService.SignIn(sessionId, commandResult.AggregateRootId, model.AccountName, false);
            _commandService.Send(new SignInAfterCommand(commandResult.AggregateRootId, Request.UserHostAddress, sessionId));

            return Json(new { success = true });
        }

        #endregion

        #region login

        [HttpGet]
        public ActionResult Login(string returnUrl)
        {
            ViewBag.ReturnUrl = returnUrl;
            return View();
        }
        [HttpPost]
        [AjaxValidateAntiForgeryToken]
        [AsyncTimeout(5000)]
        public async Task<ActionResult> Login(LoginModel model)
        {
            var account = await Task.Factory.StartNew(() => _queryService.Find(model.AccountName));
            if (account == null)
            {
                return Json(new { success = false, errorMsg = "账号不存在。" });
            }
            else if (account.Password != model.Password)
            {
                return Json(new { success = false, errorMsg = "密码不正确。" });
            }


            string sessionId =ObjectId.GenerateNewStringId();
            _authenticationService.SignIn(sessionId,account.Id, model.AccountName, model.RememberMe);
            _commandService.Send(new SignInAfterCommand(account.Id, Request.UserHostAddress, sessionId));

            return Json(new { success = true });
        }

        #endregion


        [HttpPost]
        [ValidateAntiForgeryToken]
        [Authorize]
        public ActionResult LogOff()
        {
            _commandService.Send(new SignOutAfterCommand(_contextService.CurrentAccount.AccountId, _contextService.CurrentAccount.SessionId));
            _authenticationService.SignOut();
            return RedirectToAction("login", "account");// 回到登录页
        }

        private ActionResult RedirectToLocal(string returnUrl)
        {
            if (Url.IsLocalUrl(returnUrl))
            {
                return Redirect(returnUrl);
            }
            return RedirectToAction("Index", "Home");
        }


        /// <summary>轮训[object]，直到obj不为空完成
        /// </summary>
        /// <param name="orderId"></param>
        /// <returns></returns>
        private Task<object> WaitUntilReservationCompleted(string objId)
        {
            return TimerTaskFactory.StartNew<object>(
                    () => this._queryService.Find(objId),
                    x => x != null,
                    PricedOrderPollInterval,
                    PricedOrderWaitTimeout);
        }
        private static readonly TimeSpan PricedOrderWaitTimeout = TimeSpan.FromSeconds(5);
        private static readonly TimeSpan PricedOrderPollInterval = TimeSpan.FromMilliseconds(750);

    }

}